#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Filename: buscar_ticket.py

##
# Módulos del sistema
try:
    import pygtk
    pygtk.require("2.0")
    import gtk
    import gtk.glade
except ImportError, error:
    print error
    print "Necesitas la librería gráficas gtk+pygtk"
from datetime import datetime
##
# Módulos propios
try:
    from lib.database import ClasificacionBD, EstadoBD, GrupoDeResolucionBD
    from lib.database import EmpleadoBD
except ImportError, error:
    print error
    "Error en buscar_ticket"
try:
    # !!!FIXME: no puedo cargar el modulo... ver los path
    from lib.config import WIDTH, HEIGHT
    from lib.empleado import Empleado
    from gui.msj_retroalimentacion import MensajeDeAdvertencia, MensajeDeError
    pass
except ImportError, error:
    print error
    print "Error en buscar_ticket.py"

class BuscarTicket:
    """Realiaza la actividad establecida en el CDU-02.

    Presenta la interfaz de los criterios de búsqueda de ticket.
    """
    def __init__(self, padre):
        """Constructor por defecto.

        Se levanta el archivo .glade y se preparan las cabeceras 'titulos' de
        las columnas, para mostrar el resultado.
        """
        self.gladefile = "gui/ghhp.glade"
        self.wTree = gtk.glade.XML(self.gladefile,"ConsultarTicket")
        self.window = self.wTree.get_widget("ConsultarTicket")
        self.window.resize(950, 200)
        # Establecemos el padre
        self.padre = padre
        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.window.set_transient_for(self.padre.window)
        self.hbox_79 = self.wTree.get_widget("hbox79")
        self.hbox_81 = self.wTree.get_widget("hbox81")
        self.hbox_97 = self.wTree.get_widget("hbox97")
        self.vbox_51 = self.wTree.get_widget("vbox51")
        # Creamos las cabecera de la lista de búsqueda
        self.find_view = self.wTree.get_widget("treeview14")
        self.add_find_column("Nro.", 0)
        self.add_find_column("Legajo", 1)
        self.add_find_column("Fecha\napertura", 2)
        self.add_find_column("Hora\napertura", 3)
        self.add_find_column("Usuario que\ncreo el ticket",4)
        self.add_find_column("Clasificacion\nactual",5)
        self.add_find_column("Estado\nactual",6)
        self.add_find_column("Fecha último\ncambio estado",7)
        self.add_find_column("G.R.\nactual asignado",8)
        self.find_list = gtk.ListStore(str, str, str, str, str, str, str, str,
                str)
        self.find_view.set_model(self.find_list)
        self.un_dict = {"on_button99_clicked": self.mostrar_resultados,
                "on_button100_clicked": self.limpiar_campos,
                "on_button101_clicked": self.close,
                "on_button45_clicked": self.derive,
                "on_button46_clicked": self.close_ticket,
                "on_button47_clicked": self.view_all_info_ticket,
                "on_button57_clicked": self.config_report}
        self.wTree.signal_autoconnect(self.un_dict)
        # Widget de entrada
        # Entry
        self.legajo = self.wTree.get_widget("entry80")
        self.apellido = self.wTree.get_widget("entry81")
        self.nombre = self.wTree.get_widget("entry82")
        self.nro_ticket = self.wTree.get_widget("entry86")
        # Combobox
        self.clasificacion = self.wTree.get_widget("combobox3")
        self.clasificacion.set_model(gtk.ListStore(str))
        self.estado = self.wTree.get_widget("combobox2")
        self.estado.set_model(gtk.ListStore(str))
        self.ultimo_grupo = self.wTree.get_widget("combobox1")
        self.ultimo_grupo.set_model(gtk.ListStore(str))
        self.lista_grupos = {'Todos': None}
        self.lista_clasificaciones = {'Todas': None}
        self.lista_estados = {'Todos': None}
        self.armar_combos()
        # SpinButton
        # Fecha de apertura
        self.fa_desde_dia = self.wTree.get_widget("spinbutton11")
        self.fa_desde_mes = self.wTree.get_widget("spinbutton15")
        self.fa_desde_anio = self.wTree.get_widget("spinbutton13")
        self.fa_hasta_dia = self.wTree.get_widget("spinbutton12")
        self.fa_hasta_mes = self.wTree.get_widget("spinbutton16")
        self.fa_hasta_anio = self.wTree.get_widget("spinbutton14")
        # Fecha de último cambio
        self.fu_desde_dia = self.wTree.get_widget("spinbutton22")
        self.fu_desde_mes = self.wTree.get_widget("spinbutton21")
        self.fu_desde_anio = self.wTree.get_widget("spinbutton20")
        self.fu_hasta_dia = self.wTree.get_widget("spinbutton17")
        self.fu_hasta_mes = self.wTree.get_widget("spinbutton19")
        self.fu_hasta_anio = self.wTree.get_widget("spinbutton18")
        self.empleado = None
        self.conect_entry_enter()

    def run(self):
        #self.w_create_ticket = self.wTree.get_widget("consult_ticket")
        pass

    def conect_entry_enter(self):
        """Permite generar the activate signal para los widget"""
        def grab_focus(widget, other):
            other.grab_focus()
            self.completar_campos()

        def groups(lista, n, step=1):
            for index in xrange(0, len(lista)-(n-1), step):
                yield lista[index:index+n]

        path =(self.legajo, self.apellido)
        for from0, to in groups(path, 2):
            from0.connect("activate", grab_focus, to)

    def completar_campos(self):
        """Completará los campos de apellido y nombre.

        Busca en la base de datos el nombre y apellido del Empleado con legajo
        "nro_legajo".

        Keyword arguments:
        None
        """
        nro_legajo = self.legajo.get_text()
        if nro_legajo != '':
            # Levantar el apellido y nombre con este legajo
            consulta = EmpleadoBD.selectBy(legajo = nro_legajo)
            try:
                empleado = consulta[0]
                self.apellido.set_text(empleado.apellido)
                self.nombre.set_text(empleado.nombre)
                self.empleado = empleado
                self.nro_ticket.grab_focus()
            except IndexError, error:
                print error
                msj = "Nro. de legajo inexistente en el Sistema de Personal."
                print msj
                msj_error = MensajeDeError(msj, self.window)
                msj_error.run()
                self.legajo.set_text('')
                self.legajo.grab_focus()


    def armar_combos(self):
        """Llenará con los datos correspondientes los comboboxentry.

        Buscará en la base de dato los grupos de resolucion, las clasificaciones
        y los estados activos.

        Keyword arguments:
        """

        self.ultimo_grupo.append_text("Todos")
        self.clasificacion.append_text("Todas")
        # Llenamos el de los grupos
        consulta_grupos = GrupoDeResolucionBD.select()
        for grupo in consulta_grupos:
            self.lista_grupos[grupo.nombre] = grupo
            self.ultimo_grupo.append_text(grupo.nombre)
        self.ultimo_grupo.set_active(0)
        # Llenamos el de las clasificaciones
        consulta_clasificacion = ClasificacionBD.select()
        for clasificacion in consulta_clasificacion:
            self.lista_clasificaciones[clasificacion.nombre] = clasificacion
            self.clasificacion.append_text(clasificacion.nombre)
        self.clasificacion.set_active(0)
        # Llenamos el de los estados
        consulta_estado = EstadoBD.select()
        for estado in consulta_estado:
            self.lista_estados[estado.nombre] = estado
            self.estado.append_text(estado.nombre)
        self.estado.append_text("Todos")
        self.estado.set_active(0)

    def add_find_column(self,title,columnId):
        """
            Esta funcion agrega una columna al resultado de la búsqueda
        """
        column = gtk.TreeViewColumn(title, gtk.CellRendererText(),
                text=columnId)
        column.set_resizable(True)
        column.set_sort_column_id(columnId)
        self.find_view.append_column(column)

    def datos_no_validos(self):
        """Valida los campos de fechas.

        Si fecha de apertura ó último cambio es mayor a la actual retorna True
        """
        fecha_actual = datetime.now()
        self.fecha_apertura_desde = datetime(
                self.fa_desde_anio.get_value_as_int(),
                self.fa_desde_mes.get_value_as_int(),
                self.fa_desde_dia.get_value_as_int())
        self.fecha_apertura_hasta = datetime(
                self.fa_hasta_anio.get_value_as_int(),
                self.fa_hasta_mes.get_value_as_int(),
                self.fa_hasta_dia.get_value_as_int())
        self.fecha_ultimo_cambio_desde = datetime(
                self.fu_desde_anio.get_value_as_int(),
                self.fu_desde_mes.get_value_as_int(),
                self.fu_desde_dia.get_value_as_int())
        self.fecha_ultimo_cambio_hasta = datetime(
                self.fu_hasta_anio.get_value_as_int(),
                self.fu_hasta_mes.get_value_as_int(),
                self.fu_hasta_dia.get_value_as_int())
        if (self.fecha_apertura_desde > fecha_actual or
                self.fecha_apertura_hasta > fecha_actual or
                self.fecha_ultimo_cambio_desde > fecha_actual or
                self.fecha_ultimo_cambio_hasta > fecha_actual):
            #Limpiar spines
            self.cleane_spin()
            return True, ("Las fechas de último cambio y de apertura de " +
                    "ticket\ndeben ser menores a la fecha actual")
        else:
            return False,""

    def mostrar_resultados(self, widget):
        """Llamará a la funcion buscarTicket de self.padre

        Se mostrarán todos los ticket que halla encontrado la funcion.
        """
        datos_no_validos,error = self.datos_no_validos()
        if datos_no_validos:
            msj_error = MensajeDeError(error, self.window)
            msj_error.run()
        else:
            self.window.resize(WIDTH, HEIGHT)
            lista_ticket = self.padre.mesa_de_ayuda.buscarTicket(
                    self.empleado,
                    self.tomar_valor_combo(1),#grupo
                    self.tomar_valor_combo(2),#clasificacion
                    self.tomar_valor_combo(3),#estado
                    int(self.nro_ticket.get_text()),
                    self.fecha_apertura_desde,
                    self.fecha_apertura_hasta,
                    self.fecha_ultimo_cambio_desde,
                    self.fecha_ultimo_cambio_hasta)
            if lista_ticket:
                self.vbox_51.hide()
                self.hbox_97.show()
                self.hbox_79.show()
                # Mostramos los ticket en la lista de resultado
                import pdb
                #pdb.set_trace()
                for ticket in lista_ticket:
                    lista = [
                    ticket.id,
                    ticket.empleado_solicitante.legajo,
                    ticket.fecha_creacion.strftime("%d-%m-%Y"),
                    ticket.fecha_creacion.strftime("%H:%M"),
                    ticket.usuario_creacion.u_legajo,
                    ticket.historial_de_clasificacion[-1].clasificacion.nombre,
                    ticket.historial_de_estado[-1].estados[-1].nombre,
                    ticket.historial_de_estado[-1].fecha.strftime("%d-%m-%Y"),
                    ticket.grupo_de_resolucion.nombre]
                    print lista
                    self.find_list.append(lista)
            else:
                error = "No hay ticket que cumplan con esos requisitos."
                print error
                msj_error = MensajeDeError(error, self.window)
                msj_error.run()

    def armar_empleado(self):
        """Arma una lista con los datos del empleado si es necesario.

        Si los 'entry' correspondientes al empleado estan vacios retorna None,
        sino devuelve una lista.
        """
        legajo = self.legajo.get_text()
        apellido = self.legajo.get_text()
        nombre = self.nombre.get_text()
        if (legajo or apellido or nombre):
            return [legajo, apellido, nombre]
        else:
            return None

    def tomar_valor_combo(self, combo):
        """Devuelve el valor del combo requerido.

        Retorna el valor del diccionario 'combo' que tenga como llave
        el valor de seleccion del 'combo'.

        Keyword arguments:
        combo -- type int
                    1 - Grupo de resolucion
                    2 - Clasificacion
                    3 - Estado
        """
        diccionario = {1: [self.ultimo_grupo, self.lista_grupos],
                2: [self.clasificacion, self.lista_clasificaciones],
                3: [self.estado, self.lista_estados]}

        model = diccionario[combo][0].get_model()
        index = diccionario[combo][0].get_active()
        if index and combo == 1:
            return diccionario[combo][1][model[index][0]]
        elif index and combo == 2:
            return diccionario[combo][1][model[index][0]]
        elif combo==1:
            return "Todos"
        elif combo==2:
            return "Todas"
        else:
            return diccionario[combo][1][model[index][0]]

    def derive(self,widget):
        """
            call CDU04
        """
        #self.hbox_81.show()

    def close(self,widget):
        """Cancelación de la operación.

        Se mostrará un mensaje de retroalimentación de advertencia, para
        consultar al usuario si realmente es lo que desea.
        """
        print "Operacion consulta de ticket fue cancelada"
        texto = "¿Esta seguro que desea cancelar la operación?"
        msj = MensajeDeAdvertencia(texto, self.window)
        if msj.msj.run() == gtk.RESPONSE_YES:
            self.window.destroy()
        else:
            "No quiero cancelar la operacion."
            msj.msj.destroy()
    
    def limpiar_campos(self,widget):
        """Limpiará los campos.

        Recorrerá todos los widget de 'criterios de busqueda' y los pondra en
        su estado de default.
        """
        lista_entry = [self.legajo, self.nombre, self.apellido, self.nro_ticket]
        lista_combo = [self.clasificacion, self.ultimo_grupo, self.estado]
        #Limpiamos
        for entry in lista_entry:
            entry.set_text('')
        for combo in lista_combo:
            combo.set_active(0)
        self.cleane_spin()

    def cleane_spin(self):
        """Pone los spin button en sus valores de default."""
        lista_spin_1 = [self.fa_desde_dia, self.fa_desde_mes,
                self.fa_hasta_dia, self.fa_hasta_mes,
                self.fu_desde_dia, self.fu_desde_mes,
                self.fu_hasta_dia, self.fu_hasta_mes]
        lista_spin_1999 = [self.fa_desde_anio, self.fa_hasta_anio,
                self.fu_desde_anio, self.fu_hasta_anio]
        for spin in lista_spin_1:
            spin.set_value(1)
        for spin in lista_spin_1999:
            spin.set_value(1999)

    def close_ticket(self,widget):
        pass
    def view_all_info_ticket(self,widget):
        """
            Creamos una instancia de dialog_detalle_ticket
        """
        print "Details of tickets"
        self.dialog_detalle_ticket = dialog_all_info_ticket()
        pass
    def config_report(self,widget):
        print "Config Report"
        pass
        #self.config_report = config_report()
"""
if __name__=="__main__":
    app = BuscarTicket()
    gtk.main()
    """
"""
    Class DIALOG DETALLE TICKET CDU02 - Consultar Ticket
"""
class dialog_all_info_ticket:
    """
        Extend CDU02
    """
    def __init__(self):
        self.gladefile = "ghhp.glade"
        self.wTree = gtk.glade.XML(self.gladefile,"dialog_detalle_ticket")

        #Generamos la vista del resultado
        self.find_view = self.wTree.get_widget("treeview15")
        #print self.find_view
        self.add_find_column("Fecha de cambio\nde estado", 0)
        self.add_find_column("Hora de cambio\nde estado", 1)
        self.add_find_column("Operador que\ncambio el estado", 2)
        self.add_find_column("Estado", 3)
        self.add_find_column("Grupo de resolución",4)
        self.add_find_column("Clasificación",5)
        self.find_list = gtk.ListStore(str, str, str, str, str, str)
        self.find_view.set_model(self.find_list)
        self.find_list.append(['--','--','--','--','--','--'])
        self.find_list.append(['--','--','--','--','--','--'])

    def add_find_column(self,title,columnId):
        """
            Esta funcion agrega una columna al resultado de la búsqueda
        """
        column = gtk.TreeViewColumn(title, gtk.CellRendererText(),\
                text=columnId)
        column.set_resizable(True)
        column.set_sort_column_id(columnId)
        self.find_view.append_column(column)

